home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / gdb-4.12 / gdb / go32targ.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-27  |  12.2 KB  |  485 lines

  1. /* Target-vector operations for controlling go32 processes, for GDB.
  2.    Copyright 1994 Free Software Foundation, Inc.
  3.    Contributed by DJ Delorie.
  4.  
  5. This file is part of GDB.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #include "defs.h"
  22. #include "frame.h"  /* required by inferior.h */
  23. #include "inferior.h"
  24. #include "target.h"
  25. #include "wait.h"
  26. #include "gdbcore.h"
  27. #include "command.h"
  28. #include <signal.h>
  29.  
  30. extern char **environ;
  31.  
  32. /* Forward declaration */
  33. extern struct target_ops go32_ops;
  34.  
  35. /* ╔════════════════════════════════════════════════════════════════════════════╗
  36.    ║  Go32's external debugger interface routines                ║
  37.    ╚════════════════════════════════════════════════════════════════════════════╝ */
  38.  
  39. #define SOME_PID 42
  40.  
  41. int prog_has_started = 0;
  42.  
  43. #include <sys/farptr.h>
  44. #define far
  45. #include <../go32/gotypes.h>    /* from go32 sources */
  46. #include <../go32/tss.h>
  47. #include <../go32/extdebug.h>
  48. #include <../go32/paging.h>
  49.  
  50. static ExternalDebuggerInfo edi;
  51. static TSS a_tss;
  52. static AREAS areas[MAX_AREA];
  53.  
  54. static int my_ds;
  55. static int app_ds;
  56. static int edi_seg;
  57. static int edi_ofs;
  58.  
  59. #define r_ofs(x) ((int)(&(((TSS *)0)->x)))
  60. static struct {
  61.   int tss_ofs;
  62.   int size;
  63. } regno_mapping[] = {
  64.   r_ofs(tss_eax), 4,
  65.   r_ofs(tss_ecx), 4,
  66.   r_ofs(tss_edx), 4,
  67.   r_ofs(tss_ebx), 4,
  68.   r_ofs(tss_esp), 4,
  69.   r_ofs(tss_ebp), 4,
  70.   r_ofs(tss_esi), 4,
  71.   r_ofs(tss_edi), 4,
  72.   r_ofs(tss_eip), 4,
  73.   r_ofs(tss_eflags), 4,
  74.   r_ofs(tss_cs), 2,
  75.   r_ofs(tss_ss), 2,
  76.   r_ofs(tss_ds), 2,
  77.   r_ofs(tss_es), 2,
  78.   r_ofs(tss_fs), 2,
  79.   r_ofs(tss_gs), 2
  80. };
  81.  
  82. static struct {
  83.   int go32_sig;
  84.   int gdb_sig;
  85. } sig_map[] = {
  86.   0, TARGET_SIGNAL_BUS,
  87.   1, TARGET_SIGNAL_TRAP,
  88.   2, TARGET_SIGNAL_UNKNOWN,
  89.   3, TARGET_SIGNAL_TRAP,
  90.   4, TARGET_SIGNAL_FPE,
  91.   5, TARGET_SIGNAL_SEGV,
  92.   6, TARGET_SIGNAL_ILL,
  93.   7, TARGET_SIGNAL_FPE,
  94.   8, TARGET_SIGNAL_BUS,
  95.   9, TARGET_SIGNAL_FPE,
  96.   10, TARGET_SIGNAL_BUS,
  97.   11, TARGET_SIGNAL_SEGV,
  98.   12, TARGET_SIGNAL_SEGV,
  99.   13, TARGET_SIGNAL_SEGV,
  100.   14, TARGET_SIGNAL_SEGV,
  101.   16, TARGET_SIGNAL_FPE,
  102.   31, TARGET_SIGNAL_ILL,
  103.   -1,-1
  104. };
  105.  
  106. static void go32_edi_init()
  107. {
  108.   int i;
  109.   asm("movw $0xfe01,%ax");
  110.   asm("int $0x21");
  111.   asm("movl %edx,_edi_seg");
  112.   asm("movl %eax,_edi_ofs");
  113.   asm("xor  %eax,%eax");
  114.   asm("movw %ds,%ax");
  115.   asm("movl %eax,_my_ds");
  116.   movedata(edi_seg, edi_ofs, my_ds, (int)(&edi), sizeof(edi));
  117.   movedata(edi.a_tss_seg, edi.a_tss_ofs, my_ds, (int)(&a_tss), sizeof(TSS));
  118.   app_ds = a_tss.tss_ds;
  119.   movedata(edi.areas_seg, edi.areas_ofs, my_ds, (int)areas, sizeof(areas));
  120.   for (i=0; i<MAX_AREA; i++)
  121.   {
  122.     areas[i].first_addr -= edi.app_base;
  123.     areas[i].last_addr -= edi.app_base;
  124.   }
  125. }
  126.  
  127. static void go32_edi_run_child(void)
  128. {
  129.   int i;
  130.   prog_has_started = 1;
  131.  
  132.   movedata(my_ds, (int)(&edi), edi_seg, edi_ofs, sizeof(edi));
  133.   movedata(my_ds, (int)(&a_tss), edi.a_tss_seg, edi.a_tss_ofs, sizeof(TSS));
  134.   asm("movw $0xfe00,%ax");
  135.   asm("int $0x21");
  136.   movedata(edi_seg, edi_ofs, my_ds, (int)(&edi), sizeof(edi));
  137.   movedata(edi.a_tss_seg, edi.a_tss_ofs, my_ds, (int)(&a_tss), sizeof(TSS));
  138.  
  139.   movedata(edi.areas_seg, edi.areas_ofs, my_ds, (int)areas, sizeof(areas));
  140.   for (i=0; i<MAX_AREA; i++)
  141.   {
  142.     areas[i].first_addr -= edi.app_base;
  143.     areas[i].last_addr -= edi.app_base;
  144.   }
  145. }
  146.  
  147. static int invalid_addr(word32 a, unsigned len)
  148. {
  149.   int i;
  150.   if ((int)invalid_addr > 0)
  151.     return 0;
  152.   for (i=0; i<MAX_AREA; i++)
  153.     if (a>=areas[i].first_addr && (a+len-1) <= areas[i].last_addr)
  154.       return 0;
  155.   return 1;
  156. }
  157.  
  158. static int go32_edi_read_child(word32 child_addr, void *buf, unsigned len)
  159. {
  160.   if (invalid_addr(child_addr, len))
  161.     return 0;
  162.   movedata(app_ds, child_addr, my_ds, (int)buf, len);
  163.   return 0;
  164. }
  165.  
  166. static int go32_edi_write_child(word32 child_addr, void *buf, unsigned len)
  167. {
  168.   if (invalid_addr(child_addr, len))
  169.     return 0;
  170.   movedata(my_ds, (int)buf, app_ds, child_addr, len);
  171.   return 0;
  172. }
  173.  
  174. static char *new_argv[3] = {
  175.   "gdb",
  176.   0,
  177.   0
  178. };
  179.  
  180. void
  181. init_go32_extdebug(int *argc, char ***argv)
  182. {
  183.   char *fn;
  184.   int i, v;
  185.   int tenvp;
  186.  
  187.   go32_edi_init();
  188.  
  189.   fn = (char *)malloc(edi.filename_len + 1);
  190.   movedata(edi.filename_seg, edi.filename_ofs, my_ds, (int)(fn), edi.filename_len+1);
  191.  
  192. #if 0
  193.   printf("filename: %s\n", fn);
  194.  
  195.   printf("text: %#08x - %#08x\n", areas[A_text].first_addr, areas[A_text].last_addr);
  196.   printf("data: %#08x - %#08x\n", areas[A_data].first_addr, areas[A_data].last_addr);
  197.   printf("bss:  %#08x - %#08x\n", areas[A_bss].first_addr, areas[A_bss].last_addr);
  198.  
  199.   printf("stack: %#x\n", a_tss.tss_esp);
  200. #endif
  201.  
  202.   go32_edi_read_child(a_tss.tss_esp+8, &tenvp, 4);
  203.   
  204.   new_argv[1] = fn;
  205.   
  206.   for (i=0; ; i++)
  207.   {
  208.     int ep;
  209.     char *s;
  210.     go32_edi_read_child(tenvp+i*4, &ep, 4);
  211.     if (!ep)
  212.       break;
  213.   }
  214.   environ = (char **)malloc((i+1) * sizeof(char *));
  215.  
  216.   for (i=0; ; i++)
  217.   {
  218.     int ep;
  219.     char *s;
  220.     go32_edi_read_child(tenvp+i*4, &ep, 4);
  221.     if (!ep)
  222.     {
  223.       environ[i] = 0;
  224.       break;
  225.     }
  226.     _farsetsel(app_ds);
  227.     for (v=0; _farnspeekb(ep+v); v++);
  228.     environ[i] = (char *)malloc(v+1);
  229.     go32_edi_read_child(ep, environ[i], v+1);
  230.   }
  231.   
  232.   *argc = 2;
  233.   *argv = new_argv;
  234. }
  235.  
  236. /* ───────────────────────────────────────────────────────────────────────────── */
  237.  
  238. /* special sbrk that uses local heap and zeros memory. */
  239. void *
  240. sbrk(int l)
  241. {
  242.   extern int end;
  243.   static int sold = (int)&end;
  244.   memset(sold, 0, l);
  245.   sold += l;
  246.   return (void *)(sold-l);
  247. }
  248.  
  249. /* ═════════════════════════════════════════════════════════════════════════════ */
  250.  
  251. static void
  252. go32_open(char *name, int from_tty)
  253. {
  254.   printf("Use the `run' command to run go32 programs\n");
  255. }
  256.  
  257. /* ───────────────────────────────────────────────────────────────────────────── */
  258.  
  259. static void go32_close(int quitting)
  260. {
  261. }
  262.  
  263. /* ───────────────────────────────────────────────────────────────────────────── */
  264.  
  265. static void
  266. go32_attach(char *args, int from_tty)
  267. {
  268.   printf("Use the `run' command to run go32 programs\n");
  269. }
  270.  
  271. /* ───────────────────────────────────────────────────────────────────────────── */
  272.  
  273. static void
  274. go32_detach(char *args, int from_tty)
  275. {
  276. }
  277.  
  278. /* ───────────────────────────────────────────────────────────────────────────── */
  279.  
  280. static int resume_is_step;
  281.  
  282. static void
  283. go32_resume(int pid, int step, enum target_signal siggnal)
  284. {
  285.   resume_is_step = step;
  286. }
  287.  
  288. /* ───────────────────────────────────────────────────────────────────────────── */
  289.  
  290. static int
  291. go32_wait(int pid, struct target_waitstatus *status)
  292. {
  293. /*  printf("go32_wait %d\n", pid); */
  294.   if (resume_is_step)
  295.     a_tss.tss_eflags |= 0x0100;
  296.   else
  297.     a_tss.tss_eflags &= 0xfeff;
  298.   go32_edi_run_child();
  299.   if (a_tss.tss_irqn == 0x21)
  300.   {
  301.     status->kind = TARGET_WAITKIND_EXITED;
  302.     status->value.integer = a_tss.tss_eax & 0xff;
  303.   }
  304.   else
  305.   {
  306.     int i;
  307.     status->value.sig = TARGET_SIGNAL_UNKNOWN;
  308.     for (i=0; sig_map[i].go32_sig != -1; i++)
  309.       if (a_tss.tss_irqn == sig_map[i].go32_sig)
  310.       {
  311.         status->value.sig = sig_map[i].gdb_sig;
  312.         break;
  313.       }
  314.     status->kind = TARGET_WAITKIND_STOPPED;
  315.   }
  316.   return SOME_PID;
  317. }
  318.  
  319. /* ───────────────────────────────────────────────────────────────────────────── */
  320.  
  321. static void
  322. go32_fetch_registers(int regno)
  323. {
  324.   if (regno >= 0)
  325.     supply_register(regno, (char *)&a_tss + regno_mapping[regno].tss_ofs);
  326.   else
  327.   {
  328.     int r;
  329.     for (r=0; r<sizeof(regno_mapping)/sizeof(regno_mapping[0]); r++)
  330.       supply_register(r, (char *)&a_tss + regno_mapping[r].tss_ofs);
  331.   }
  332. }
  333.  
  334. /* ───────────────────────────────────────────────────────────────────────────── */
  335.  
  336. static void store_register(int regno)
  337. {
  338.   char *rp = (char *)&a_tss + regno_mapping[regno].tss_ofs;
  339.   int v = *(int *)(®isters[REGISTER_BYTE(regno)]);
  340.   switch (regno_mapping[regno].size)
  341.   {
  342.     case 4:
  343.       *(int *)rp = v;
  344.       break;
  345.     case 2:
  346.       *(short *)rp = v;
  347.       break;
  348.   }
  349. }
  350.  
  351. static void
  352. go32_store_registers(int regno)
  353. {
  354.   if (regno >= 0)
  355.     store_register(regno);
  356.   else
  357.   {
  358.     int r;
  359.     for (r=0; r<sizeof(regno_mapping)/sizeof(regno_mapping[0]); r++)
  360.       store_register(regno);
  361.   }
  362. }
  363.  
  364. /* ───────────────────────────────────────────────────────────────────────────── */
  365.  
  366. static void
  367. go32_prepare_to_store(void)
  368. {
  369. }
  370.  
  371. /* ───────────────────────────────────────────────────────────────────────────── */
  372.  
  373. static int
  374. go32_xfer_memory(CORE_ADDR memaddr, char *myaddr, int len, int write,
  375.          struct target_ops *target)
  376. {
  377. /*  printf("go32_xfer_memory %x %x %d %d\n", memaddr, myaddr, len, write); */
  378.   if (write)
  379.     go32_edi_write_child(memaddr, myaddr, len);
  380.   else
  381.     go32_edi_read_child(memaddr, myaddr, len);
  382.   return len;
  383. }
  384.  
  385. /* ───────────────────────────────────────────────────────────────────────────── */
  386.  
  387. static void
  388. go32_files_info(struct target_ops *target)
  389. {
  390.   printf_filtered("You are running a go32 program called `%s'\n", new_argv[1]);
  391. }
  392.  
  393. /* ───────────────────────────────────────────────────────────────────────────── */
  394.  
  395. static void
  396. go32_kill_inferior(void)
  397. {
  398.   /* nothing to do */
  399. }
  400.  
  401. /* ───────────────────────────────────────────────────────────────────────────── */
  402.  
  403. static void
  404. go32_create_inferior(char *exec_file, char *args, char **env)
  405. {
  406.   if (prog_has_started)
  407.   {
  408.     printf("The program has been started once already.  Please quit and restart gdb.\n");
  409.     return;
  410.   }
  411.   inferior_pid = SOME_PID;
  412.   push_target(&go32_ops);
  413.   clear_proceed_status();
  414.   proceed((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
  415. }
  416.  
  417. /* ───────────────────────────────────────────────────────────────────────────── */
  418.  
  419. static void
  420. go32_mourn_inferior(void)
  421. {
  422.   unpush_target(&go32_ops);
  423. }
  424.  
  425. /* ───────────────────────────────────────────────────────────────────────────── */
  426.  
  427. static int go32_can_run(void)
  428. {
  429.   return 1;
  430. }
  431.  
  432. /* ───────────────────────────────────────────────────────────────────────────── */
  433.  
  434. static void ignore(void) {}
  435. static void ignore2(char *a,int b) {}
  436.  
  437. /* ═════════════════════════════════════════════════════════════════════════════ */
  438.  
  439. struct target_ops go32_ops = {
  440.   "go32",            /* to_shortname */
  441.   "go32 target process",    /* to_longname */
  442.   "Program loaded by go32, when gdb is used as an external debugger",    /* to_doc */
  443.   go32_open,            /* to_open */
  444.   go32_close,            /* to_close */
  445.   go32_attach,            /* to_attach */
  446.   go32_detach,             /* to_detach */
  447.   go32_resume,            /* to_resume */
  448.   go32_wait,            /* to_wait */
  449.   go32_fetch_registers,        /* to_fetch_registers */
  450.   go32_store_registers,        /* to_store_registers */
  451.   go32_prepare_to_store,    /* to_prepare_to_store */
  452.   go32_xfer_memory,        /* to_xfer_memory */
  453.   go32_files_info,        /* to_files_info */
  454.   memory_insert_breakpoint,    /* to_insert_breakpoint */
  455.   memory_remove_breakpoint,    /* to_remove_breakpoint */
  456.   ignore,            /* to_terminal_init */
  457.   ignore,             /* to_terminal_inferior */
  458.   ignore,            /* to_terminal_ours_for_output */
  459.   ignore,            /* to_terminal_ours */
  460.   ignore2,            /* to_terminal_info */
  461.   go32_kill_inferior,        /* to_kill */
  462.   0,                /* to_load */
  463.   0,                /* to_lookup_symbol */
  464.   go32_create_inferior,        /* to_create_inferior */
  465.   go32_mourn_inferior,        /* to_mourn_inferior */
  466.   go32_can_run,            /* to_can_run */
  467.   0,                 /* to_notice_signals */
  468.   process_stratum,        /* to_stratum */
  469.   0,                /* to_next */
  470.   1,                /* to_has_all_memory */
  471.   1,                /* to_has_memory */
  472.   1,                /* to_has_stack */
  473.   1,                /* to_has_registers */
  474.   1,                /* to_has_execution */
  475.   0,                /* sections */
  476.   0,                /* sections_end */
  477.   OPS_MAGIC            /* to_magic */
  478. };
  479.  
  480. void
  481. _initialize_inftarg ()
  482. {
  483.   add_target (&go32_ops);
  484. }
  485.